<template>
  <div class="wo-wrap" :style="{ height: px(height) }">
    <div class="toolbar toolbar--compact">
      <div class="left">
        

        <!-- <el-form-item label="工单状态">
          <el-select
              v-model.number="filter.status"
              placeholder="请选择工单状态"
              @change="applySearch"
              clearable
              @clear="applySearch"
            >
              <el-option
                v-for="dict in asset_order_status"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              ></el-option>
            </el-select>
        </el-form-item> -->

        <el-form-item label="">
          <el-input
            v-model.trim="filter.workKw"
            placeholder="作业内容搜索"
            clearable
            @keyup.enter="applySearch"
            style="width: 160px"
            @clear="applySearch"
          >
            <template #prefix
              ><el-icon><Search /></el-icon
            ></template>
          </el-input>
        </el-form-item>

        <el-form-item label="">
          <el-select
            v-model="filter.source"
            clearable
            placeholder="维护类型"
            @change="applySearch"
            style="width: 160px"
          >
            <el-option
              v-for="opt in sourceOptions"
              :key="opt.value"
              :label="opt.label"
              :value="opt.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="">
          <SingleDateRange
            v-model="filter.dateRangeDay"
            @normalized="onNorm"
            @change="onDateChange"
            placeholder="维护日期范围选择"
            style="width: 400px"
          />
        </el-form-item>
       


        <!-- <el-form-item label="">
          <DateRangePicker
            v-model="filter.dateRangeDay"
            :placeholder="['起始日期', '截止日期']"
            :shortcuts="[
              {
                text: '本月',
                value: () => {
                  const now = new Date();
                  const s = new Date(now.getFullYear(), now.getMonth(), 1);
                  const e = new Date(now.getFullYear(), now.getMonth() + 1, 0);
                  return [s, e];
                },
              },
              {
                text: '近7天',
                value: () => [
                  new Date(Date.now() - 6 * 86400000),
                  new Date(),
                ],
              },
            ]"
            @normalized="onNorm"
            @change="onDateChange"
            style="width: 220px"
          />
        </el-form-item> -->

      </div>
      <div class="right">
        <el-form-item>
          <el-button type="primary" :icon="Search" @click="applySearch"
            >查询</el-button
          >
          <el-button :icon="Refresh" @click="resetAndSearch">重置</el-button>
        </el-form-item>
      </div>
    </div>

    <div class="wo-body" v-loading="innerLoading">
      <!-- 空状态 -->
      <el-empty
        v-if="!list.length && !innerLoading"
        description="暂无工单数据"
        class="empty-card"
      />

      <!-- 表格（卡片） -->
      <div v-else class="table-card">
        <el-table
          :data="list"
          border
          stripe
          :size="tableSize"
          :height="'100%'"
          :header-cell-class-name="() => 'wo-th'"
          :row-class-name="rowClassName"
          :default-sort="defaultSort"
          highlight-current-row
          @sort-change="onSortChange"
        >
          <!-- <el-table-column type="expand" width="44">
  <template #default="{ row }">
    <div v-if="hasAny(row)" class="info-grid" :class="gridClass(row)">

     
      <section v-if="hasAttachments(row)" class="info-card">
        <header class="info-card__title">
          
        </header>
        <AttachmentList :attachments="row.attachments" :orderId="row.id" compact />
      </section>

       
      <section v-if="hasNode(row)" class="info-card">
        <header class="info-card__title"><span>设备信息</span></header>
        <el-descriptions class="kv" :column="2" size="small">
          <el-descriptions-item label="名称">{{ row.node?.name || '-' }}</el-descriptions-item>
          <el-descriptions-item label="编码">{{ row.node?.code || '-' }}</el-descriptions-item>
          <el-descriptions-item label="型号">{{ row.node?.model || '-' }}</el-descriptions-item>
          <el-descriptions-item label="规格">{{ row.node?.specification || '-' }}</el-descriptions-item>
          <el-descriptions-item label="品牌">{{ row.node?.brand || '-' }}</el-descriptions-item>
        </el-descriptions>
      </section>

      
      <section v-if="hasSpare(row)" class="info-card">
        <header class="info-card__title"><span>备件明细</span></header>
        <el-table :data="row.spareInfos || []" size="small" stripe border={false} class="spare-table">
          <el-table-column prop="code" label="编号" width="140" />
          <el-table-column prop="name" label="名称" min-width="160" />
          <el-table-column prop="qty" label="数量" width="90">
            <template #default="{ row }"><el-tag type="success" effect="light">{{ row.qty }}</el-tag></template>
          </el-table-column>
          <el-table-column prop="stockAvailable" label="可用" width="90" />
          <el-table-column prop="stockTotal" label="总量" width="90" />
        </el-table>
      </section>

    </div>
    <el-empty v-else description="无附件 / 备件 / 设备信息" />
  </template>
</el-table-column> -->

          <el-table-column
            prop="createTime"
            label="维护日期"
            width="160"
            show-overflow-tooltip
            sortable="custom"
          />
          <el-table-column
            prop="woCode"
            label="工单号"
            min-width="140"
            show-overflow-tooltip
          />

          <el-table-column label="维护类型" width="120" show-overflow-tooltip>
            <template #default="{ row }">
              {{ sourceText(row.source) }}
            </template>
          </el-table-column>

          <el-table-column label="工单状态" width="110" align="center">
            <template #default="{ row }">
              <el-tag :type="statusTagByVal(row.status)" :size="tableSize">
                {{ statusLabel(row.status) }}
              </el-tag>
            </template>
          </el-table-column>

          <!-- 作业内容 + 附件展示 -->
          <!-- <el-table-column label="作业内容" min-width="220">
            <template #default="{ row }">
              {{ row.woContent }}
              <AttachmentCellMini :attachments="row.attachments || []" />
            </template>
          </el-table-column> -->

          <el-table-column label="作业内容" min-width="220">
            <template #default="{ row }">
              <template
                v-if="
                  (row.woContent && row.woContent.trim()) ||
                  (row.attachments && row.attachments.length)
                "
              >
                <!-- 有内容或附件时正常展示 -->
                <span>{{ row.woContent || "" }}</span>
                <AttachmentCellMini :attachments="row.attachments || []" />
              </template>
              <template v-else>
                <!-- 都没有时显示 -- -->
                -
              </template>
            </template>
          </el-table-column>

          <!-- <el-table-column label="作业内容" min-width="360">
            <template #default="{ row }">
              <AttachmentCell
                :attachments="row.attachments || []"
                :order-id="row.id"
              />
            </template>
          </el-table-column> -->

          <el-table-column label="故障时间" width="140" show-overflow-tooltip>
            <template #default="{ row }">{{
              planFromCreate(row.submitTime)
            }}</template>
          </el-table-column>

          <el-table-column label="故障类型" width="140" show-overflow-tooltip>
            <template #default="{ row }">
              {{ faultTypeText(row.faultType) }}</template
            >
          </el-table-column>
          <el-table-column label="故障现象" width="140" show-overflow-tooltip>
            <template #default="{ row }">{{ row.faultDesc || '-' }}</template>
          </el-table-column>

          <el-table-column label="作业工时" width="140" show-overflow-tooltip>
            <template #default="{ row }">
              {{ diffHours(row.actualStartTime, row.actualEndTime) }}</template
            >
          </el-table-column>

          <el-table-column
            label="影响生产工时"
            width="140"
            show-overflow-tooltip
          >
            <template #default="{ row }">
              {{ diffHours(row.submitTime, row.actualEndTime) }}</template
            >
          </el-table-column>

          <!-- <el-table-column label="开始时间" width="140" show-overflow-tooltip>
            <template #default="{ row }">{{
              fmtDateTime(row.actualStartTime)
            }}</template>
          </el-table-column>
          <el-table-column label="完成时间" width="140" show-overflow-tooltip>
            <template #default="{ row }">{{
              fmtDateTime(row.actualEndTime)
            }}</template>
          </el-table-column> -->

          <!-- 备件信息（由原“计划信息”替换） -->
          <el-table-column
            label="备件信息"
            header-align="center"
            align="center"
            header-class-name="group-plan-header"
          > 
            <!-- <el-table-column
              label="编号"
              width="140"
              align="center"
              class-name="group-plan-body"
            >
              <template #default="scope">
                <div
                  v-if="
                    Array.isArray(scope.row.spareInfos) &&
                    scope.row.spareInfos.length
                  "
                  class="stack num-col"
                >
                  <div
                    v-for="(sp, i) in scope.row.spareInfos"
                    :key="sp.spareId ?? sp.code ?? i"
                    class="line"
                  >
                    {{ sp.code || "-" }}
                  </div>
                </div>
                <span v-else>-</span>
              </template>
            </el-table-column> -->

            
            <el-table-column
              label="更换备件名称"
              min-width="160"
              align="left"
              class-name="group-plan-body"
            >
              <template #default="scope">
                <div
                  v-if="
                    Array.isArray(scope.row.spareInfos) &&
                    scope.row.spareInfos.length
                  "
                  class="stack"
                >
                  <div
                    v-for="(sp, i) in scope.row.spareInfos"
                    :key="sp.spareId ?? sp.code ?? i"
                    class="line one-line"
                  >
                    <el-tooltip :content="sp.name || '-'" placement="top">
                      <span>{{ sp.name || "-" }}</span>
                    </el-tooltip>
                  </div>
                </div>
                <span v-else>-</span>
              </template>
            </el-table-column>

           
            <el-table-column
              label="更换备件数量"
              min-width="120"
              align="center"
              class-name="group-plan-body"
            >
              <template #default="scope">
                <div
                  v-if="
                    Array.isArray(scope.row.spareInfos) &&
                    scope.row.spareInfos.length
                  "
                  class="stack num-col"
                >
                  <div
                    v-for="(sp, i) in scope.row.spareInfos"
                    :key="sp.spareId ?? sp.code ?? i"
                    class="line"
                  >
                    {{ sp.qty ?? "-" }}
                  </div>
                </div>
                <span v-else>-</span>
              </template>
            </el-table-column>

            
            <!-- <el-table-column
              label="可用"
              width="90"
              align="center"
              class-name="group-plan-body"
            >
              <template #default="scope">
                <div
                  v-if="
                    Array.isArray(scope.row.spareInfos) &&
                    scope.row.spareInfos.length
                  "
                  class="stack num-col"
                >
                  <div
                    v-for="(sp, i) in scope.row.spareInfos"
                    :key="sp.spareId ?? sp.code ?? i"
                    class="line"
                  >
                    {{ sp.stockAvailable ?? "-" }}
                  </div>
                </div>
                <span v-else>-</span>
              </template>
            </el-table-column>

            
            <el-table-column
              label="总量"
              width="90"
              align="center"
              class-name="group-plan-body"
            >
              <template #default="scope">
                <div
                  v-if="
                    Array.isArray(scope.row.spareInfos) &&
                    scope.row.spareInfos.length
                  "
                  class="stack num-col"
                >
                  <div
                    v-for="(sp, i) in scope.row.spareInfos"
                    :key="sp.spareId ?? sp.code ?? i"
                    class="line"
                  >
                    {{ sp.stockTotal ?? "-" }}
                  </div>
                </div>
                <span v-else>-</span>
              </template>
            </el-table-column> -->
          </el-table-column>

          <el-table-column
            prop="remark"
            label="备注"
            min-width="200"
            show-overflow-tooltip
          />

          <!-- <el-table-column label="操作" fixed="right" width="180" align="center">
            <template #default="{ row }">
              <el-button link :size="tableSize" type="primary" :icon="Search" @click="$emit('view', row)">查看</el-button>
              <el-button link :size="tableSize" type="warning" :icon="Edit" @click="$emit('edit', row)">编辑</el-button>
              <el-popconfirm title="确定删除该工单？" @confirm="$emit('remove', row)">
                <template #reference>
                  <el-button link :size="tableSize" type="danger" :icon="Delete">删除</el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column> -->
        </el-table>
      </div>

      <el-pagination
        v-if="pager.total > 0"
        class="wo-pager"
        background
        :size="tableSize"
        layout="total, sizes, prev, pager, next, jumper"
        :page-sizes="pager.pageSizes"
        :total="pager.total"
        :page-size="pager.pageSize"
        :current-page="pager.pageNum"
        @current-change="onPageChange"
        @size-change="onSizeChange"
      />
    </div>
  </div>
</template>

<script setup>
import {
  ref,
  computed,
  reactive,
  watch,
  onMounted,
  getCurrentInstance,
} from "vue";
import { Delete, Edit, Refresh, Search } from "@element-plus/icons-vue";
import AttachmentList from "@/components/sbtz/file/AttachmentList.vue";
import AttachmentCell from "@/components/sbtz/file/AttachmentCell.vue";
import AttachmentCellMini from "@/components/sbtz/file/AttachmentCellMini.vue";

const innerLoading = ref(false);
const dataSource = ref([]);

const { proxy } = getCurrentInstance();
const { asset_node_type } = proxy.useDict("asset_node_type");
const { asset_order_status } = proxy.useDict("asset_order_status");

// 搜索条件
const filter = reactive({
  type: null,
  workKw: "",
  dateRangeDay: null,
  orderByColumn: "createTime",
  isAsc: "desc",
  source: null,
  status: null,
});

const props = defineProps({
  row: { type: [Array, Object], default: () => [] },
  title: { type: String, default: "设备维护/维修 · 工单清单" },
  height: { type: [Number, String], default: "72vh" },
  searchApi: { type: Function, default: null },
  size: { type: String, default: "small" },
  autoLoad: { type: Boolean, default: true },
});
defineEmits(["view", "edit", "remove"]);

const tableSize = computed(() => props.size || "small");
const px = (v) => (typeof v === "number" ? `${v}px` : v);

const sourceOptions = [
  // { label: "全部", value: "ALL" },
  { label: "手动", value: "MANUAL" },
  { label: "自主维护", value: "AUTO_PREDICT" },
  { label: "预防性自动", value: "AUTO_PM" },
];

const sourceMap = Object.fromEntries(
  sourceOptions.map((o) => [o.value, o.label])
);
const sourceText = (v) => (v ? sourceMap[v] ?? v : "-");

const hasAttachments = (row) =>
  Array.isArray(row.attachments) && row.attachments.length > 0;
const hasSpare = (row) =>
  Array.isArray(row.spareInfos) && row.spareInfos.length > 0;
const hasNode = (row) =>
  !!(row.node && (row.node.name || row.node.code || row.node.model));
const hasAny = (row) => hasAttachments(row) || hasSpare(row) || hasNode(row);

const gridClass = (row) => {
  let c = 0;
  if (hasAttachments(row)) c++;
  if (hasNode(row)) c++;
  if (hasSpare(row)) c++;
  return `cols${Math.max(c, 1)}`;
};

// 分页
const pager = reactive({
  pageNum: 1,
  pageSize: 10,
  total: 0,
  pageSizes: [10, 20, 50, 100],
});

// 默认排序
const defaultSort = computed(() => ({
  prop: filter.orderByColumn || "createTime",
  order: filter.isAsc === "ascending" ? "asc" : "desc",
}));

/** 将后端的 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss 字符串轻量格式化为 19 位 */
function fmtDateTime(v) {
  if (!v) return "-";
  const s = String(v).trim();
  // 已是完整格式：直接裁 19 位
  if (/^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}$/.test(s)) return s.slice(0, 19);
  // 只有日期：补上 00:00:00
  if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return `${s} 00:00:00`;
  // 兜底：尝试 Date 解析
  const d = new Date(s);
  if (isNaN(d)) return s;
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  const hh = String(d.getHours()).padStart(2, "0");
  const mm = String(d.getMinutes()).padStart(2, "0");
  const ss = String(d.getSeconds()).padStart(2, "0");
  return `${y}-${m}-${day} ${hh}:${mm}:${ss}`;
}

/** 安全解析 yyyy-MM-dd HH:mm:ss / yyyy-MM-dd / 时间戳 */
function parseDateTime(v) {
  if (!v) return null;
  if (typeof v === "number") {
    const d = new Date(v);
    return isNaN(d) ? null : d;
  }
  const s = String(v).trim();
  // 兼容两种常见格式
  const m = s.match(/^(\d{4})-(\d{2})-(\d{2})(?:\s+(\d{2}):(\d{2}):(\d{2}))?$/);
  if (m) {
    const [, Y, M, D, h = "00", m2 = "00", s2 = "00"] = m;
    const d = new Date(+Y, +M - 1, +D, +h, +m2, +s2);
    return isNaN(d) ? null : d;
  }
  const d = new Date(s);
  return isNaN(d) ? null : d;
}

/** 计算两时间相差多少小时（保留 2 位小数）。任一为空返回 '-' */
function diffHours(start, end) {
  const s = parseDateTime(start);
  const e = parseDateTime(end);
  if (!s || !e) return "-";
  const ms = e.getTime() - s.getTime();
  const hours = ms / (1000 * 60 * 60);
  // 小于 0（异常）时也给出数值，可按需改成 '-'
  return hours.toFixed(2);
}

/** 故障类型文案 */
function faultTypeText(v) {
  // 你的约定：1突发性 2渐发性 3间歇性 0无故障（或 null/undefined）
  const map = {
    0: "无故障",
    1: "突发性故障",
    2: "渐发性故障",
    3: "间歇性故障",
  };
  // 兼容字符串数字
  const key = v === 0 || v ? String(v) : "0";
  return map[key] ?? "无故障";
}

watch(
  () => props.row?.id,
  (id) => {
    pager.pageNum = 1;
    if (id) {
      doSearch();
    } else {
      dataSource.value = [];
      pager.total = 0;
    }
  },
  { immediate: true }
);

function normalize(item = {}) {
  return {
    id: item.id,
    woCode: item.woCode,
    source: item.source || "-",
    planStartTime: item.planStartTime || "-",
    woContent: item.woContent || "-",
    orderType: item.orderType || "-",
    status: item.status || item.state,
    createTime: item.createTime,
  };
}

onMounted(applySearch);
watch(
  () => props.row?.id,
  () => applySearch()
);

const list = computed(() => dataSource.value || []);

function onNorm(range) {
  const toYmd = (d) =>
    typeof d === "string"
      ? d.slice(0, 10)
      : `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(
          2,
          "0"
        )}-${String(d.getDate()).padStart(2, "0")}`;
  filter.dateRangeDay = Array.isArray(range) ? range.map(toYmd) : null;
}

function buildParams() {
  const day = Array.isArray(filter.dateRangeDay) ? filter.dateRangeDay : null;
  const [startTime, endTime] =
    day && day.length === 2
      ? [day[0] + " 00:00:00", day[1] + " 23:59:59"]
      : [null, null];

  const params = {
    pageNum: pager.pageNum,
    pageSize: pager.pageSize,
    equipmentId: props.row?.id,
    orderType: filter.type === "ALL" ? null : filter.type,
    source: filter.source === "ALL" ? null : filter.source,
    woContent: filter.workKw || null,
    orderByColumn: filter.orderByColumn,
    isAsc: filter.isAsc,
    status: filter.status,
    "params[beginTime]": startTime,
    "params[endTime]": endTime,
  };
  Object.keys(params).forEach(
    (k) => params[k] === undefined && delete params[k]
  );
  return params;
}

function onDateChange() {
  filter.pageNum = 1;
  doSearch();
}

async function doSearch() {
  if (!props.row?.id) {
    dataSource.value = [];
    pager.total = 0;
    return;
  }
  innerLoading.value = true;
  try {
    const params = buildParams();
    const result =
      typeof props.searchApi === "function"
        ? await props.searchApi(params)
        : [];

    const rows = Array.isArray(result) ? result : result?.rows || [];
    const total = Array.isArray(result) ? rows.length : result?.total ?? 0;

    // dataSource.value = rows.map(normalize)
    console.log(rows);
    dataSource.value = rows;
    pager.total = total;
  } catch (e) {
    console.error("查询失败：", e);
    dataSource.value = [];
    pager.total = 0;
  } finally {
    innerLoading.value = false;
  }
}

function applySearch() {
  pager.pageNum = 1;
  doSearch();
}

function resetAndSearch() {
  filter.type = null;
  filter.source = null;
  filter.workKw = "";
  filter.dateRangeDay = null;
  filter.orderByColumn = "createTime";
  filter.isAsc = "desc";
  filter.status = null;
  pager.pageNum = 1;
  pager.pageSize = 10;
  doSearch();
}

function onSortChange({ prop, order }) {
  filter.orderByColumn = prop || "createTime";
  filter.isAsc =
    order === "ascending" ? "asc" : order === "descending" ? "desc" : "desc";
  doSearch();
}

function onPageChange(page) {
  pager.pageNum = page;
  doSearch();
}
function onSizeChange(size) {
  pager.pageSize = size;
  pager.pageNum = 1;
  doSearch();
}

/* 工具函数 */
function parseDateSafe(input) {
  if (!input) return null;
  const m = String(input).match(
    /^(\d{4})-(\d{2})-(\d{2})(?:\s+(\d{2}):(\d{2})(?::(\d{2}))?)?$/
  );
  if (m) {
    const [, y, mo, d, hh = "00", mm = "00", ss = "00"] = m;
    return new Date(+y, +mo - 1, +d, +hh, +mm, +ss);
  }
  const d = new Date(input);
  return isNaN(d) ? null : d;
}
function addMonths(date, months) {
  const d = new Date(date.getTime());
  const day = d.getDate();
  d.setMonth(d.getMonth() + months);
  if (d.getDate() !== day) d.setDate(0);
  return d;
}
function fmtYMD(date) {
  const y = date.getFullYear();
  const m = String(date.getMonth() + 1).padStart(2, "0");
  const d = String(date.getDate()).padStart(2, "0");
  return `${y}-${m}-${d}`;
}
function planFromCreate(createTime) {
  const d = parseDateSafe(createTime);
  if (!d) return "-";
  const target = addMonths(d, 11);
  return fmtYMD(target);
}
function statusTag(s) {
  if (["完成", "已完成", "已关闭"].includes(s)) return "success";
  if (["进行中", "处理中"].includes(s)) return "warning";
  return "info";
}
function rowClassName({ row }) {
  if (["完成", "已完成", "已关闭"].includes(row.status)) return "row-done";
  if (["进行中", "处理中"].includes(row.status)) return "row-going";
  return "";
}

// ---- 状态字典（来自后端 dict：asset_order_status） ----
// 兼容 useDict 返回 ref/数组
const _dictArray = (d) =>
  Array.isArray(d) ? d : Array.isArray(d?.value) ? d.value : [];

// value -> label 映射
const statusVal2Label = computed(() => {
  const arr = _dictArray(asset_order_status);
  const map = new Map();
  arr.forEach((d) => map.set(String(d.value), d.label));
  return map;
});

// value -> el-tag type 映射
const statusVal2Tag = computed(() => {
  const arr = _dictArray(asset_order_status);
  const map = new Map();
  console.log(arr);
  arr.forEach((d) => {
    const t = (d.elTagClass || d.elTagType || "").toLowerCase();
    let type = "info";
    if (/success|green|ok/.test(t)) type = "success";
    else if (/warn|yellow|warning/.test(t)) type = "warning";
    else if (/danger|error|red/.test(t)) type = "danger";
    map.set(String(d.value), type);
  });
  return map;
});

// 模板里可直接用这两个函数
const statusLabel = (v) => {
  const map = statusVal2Label.value;
  return map.get(String(v)) ?? v ?? "-";
};

const statusTagByVal = (v) => {
  const map = statusVal2Tag.value;
  return map.get(String(v)) ?? "info";
};
</script>

<style scoped>
/* 容器 */
.wo-body {
  height: 100%;
  padding: 1px 14px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  box-sizing: border-box;
}

.wo-wrap {
  display: flex;
  flex-direction: column;
  overflow: hidden; /* ✅ 外层不滚动 */
  height: 100%; /* 你已有 :style 传入高度也可保留 */
}

/* 工具栏布局 */

.toolbar-grid {
  display: flex;
  align-items: center;
  gap: 3px 3px;
  flex-wrap: nowrap; /* ✅ 关键：不换行 */
  min-width: 0; /* 允许子项收缩 */
}
@media (max-width: 1200px) {
  .toolbar-grid {
    flex-wrap: wrap;
  } /* 小屏可换行 */
}

.w-200 {
  width: 160px;
}
.w-240 {
  width: 240px;
}

/* 按钮区：靠右 + 不换行 */
.ml-auto {
  margin-left: auto;
  display: flex;
  gap: 1px;
  flex-wrap: nowrap; /* ✅ 不换行 */
  white-space: nowrap; /* ✅ 文本不换行（按钮始终并排） */
}
@media (max-width: 1024px) {
  .ml-auto {
    margin-left: 0;
  }
}

/* 空状态 */
.empty-card {
  padding: 28px 0;
}

/* 表格卡片 */

/* 表头样式（近似你的截图） */
:deep(.wo-th) {
  background: #f8fafc;
  color: #1f2937;
  font-weight: 600;
  border-bottom: 1px solid #edf0f4;
}

/* 行高与悬停 */
:deep(.el-table__row) {
  transition: background 0.15s ease;
}
:deep(.el-table__row:hover) td {
  background: #f7fbff !important;
}

/* 完成/进行中行弱高亮 */
.row-done :deep(td) {
  background: #fafdf8;
}
.row-going :deep(td) {
  background: #fffdf5;
}

/* 分页 */
/* 分页粘在可视区底部（相对于滚动容器） */
.wo-pager {
  position: sticky;
  bottom: 0;
  z-index: 5;
  background: #fff; /* 避免与表格重叠时透出 */
  border-top: 1px solid #eef2f6;
  padding: 10px 8px;
  display: flex;
  justify-content: flex-end;
}

/* 输入控件统一风格 */
:deep(.el-input__wrapper),
:deep(.el-select__wrapper) {
  box-shadow: none;
  border: 1px solid #e6ebf1;
  background: #fff;
}
:deep(.el-input__wrapper.is-focus),
:deep(.el-select__wrapper.is-focused) {
  border-color: #6aa6ff;
  box-shadow: 0 0 0 3px rgba(79, 140, 255, 0.12);
}

/* 小尺寸更紧凑一些 */
:deep(.el-table--small .el-table__cell) {
  padding: 10px 8px;
}

/* --- 卡片外观：圆角 + 细边 + 阴影 --- */
.table-card {
  border: 1px solid #edf0f4;
  border-radius: 10px;
  box-shadow: 0 6px 20px rgba(28, 39, 60, 0.06);
  overflow: hidden; /* 让表头/四角都跟着圆角 */
  background: #fff;
  box-shadow: 0 0 0 3px #fcfafa;
}

/* --- 统一表格基色：浅灰表头、细分隔线、悬停淡蓝 --- */
:deep(.el-table) {
  --table-border: #eef2f6;
  --table-header: #f7f9fc;
  --row-hover: #f7fbff;
  --text: #1f2937;
}

/* 去掉 Element 顶部那条默认细线 */
:deep(.el-table__inner-wrapper::before) {
  background-color: transparent;
}

/* 表头：浅灰底、加粗、稍大一点的间距 */
:deep(.el-table__header-wrapper th) {
  background: var(--table-header);
  color: var(--text);
  font-weight: 600;
  border-bottom: 1px solid var(--table-border);
}

/* 单元格分隔线更轻、更整齐 */

:deep(.el-table__row td:last-child),
:deep(.el-table__header-wrapper th:last-child) {
  border-right: none; /* 最后一列不画右边线，边界更干净 */
}

/* 行悬停：淡蓝 */
:deep(.el-table__row:hover) td {
  background: var(--row-hover) !important;
}

/* 小尺寸行高略紧凑（你已启用 small） */
:deep(.el-table--small .el-table__cell) {
  padding: 10px 10px;
}

/* --- 胶囊 Tag（状态/需备件等）更像设计稿 --- */
:deep(.el-tag) {
  border-radius: 999px;
  height: 22px;
  line-height: 20px;
  padding: 0 10px;
  border: 0;
  font-weight: 600;
}

/* 如果你用到“需要/不需要”的 Tag，可这样配色： */
.tag-need {
  background: #e8f6ef;
  color: #16a34a;
} /* 需要 = 绿色 */
.tag-noneed {
  background: #fff3e6;
  color: #d97706;
} /* 不需要 = 橙色 */

/* 你现有的状态 tag 也会因上面的通用样式更圆润 */

.plan-pane {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-radius: 10px;
  padding: 10px 12px;
}
.toolbar .left {
  display: flex;
  gap: 10px;
  padding: 1px 10px;
  align-items: center;
}
.toolbar .right {
  display: flex;
  gap: 8px;
}
.plan-table {
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.05);
}
.pager {
  display: flex;
  justify-content: flex-end;
}

/* 紧凑工具条（图1风格） */
.toolbar--compact {
  --ctl-h: 28px; /* 小号控件高度 */
  --ctl-fs: 12px; /* 小号字体 */
  padding: 6px 10px; /* 更紧的左右内边距 */
}
.toolbar--compact .left {
  gap: 8px;
}
.toolbar--compact .right {
  gap: 6px;
}

/* 统一控件尺寸与描边（Element Plus 用 box-shadow 作边框） */
.toolbar--compact :deep(.el-input__wrapper),
.toolbar--compact :deep(.el-select .el-select__wrapper),
.toolbar--compact :deep(.el-range-editor) {
  height: var(--ctl-h);
  font-size: var(--ctl-fs);
  padding: 0 8px;
}

/* 小号按钮 */
.toolbar--compact :deep(.el-button) {
  height: var(--ctl-h);
  padding: 0 10px;
  font-size: var(--ctl-fs);
}

/* 占位符更轻一些（可选） */
.toolbar--compact :deep(.el-input__inner::placeholder),
.toolbar--compact :deep(.el-range-editor__input::placeholder) {
  color: var(--el-text-color-placeholder);
}

/* 展开区：根据类名决定列数 */
/* 三列网格：自动 1/2/3 列 */
.info-grid {
  display: grid;
  gap: 16px;
  align-items: start;
}
.info-grid.cols3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.info-grid.cols2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.info-grid.cols1 {
  grid-template-columns: 1fr;
}

/* 统一卡片风格：简洁、留白、轻阴影 */
.info-card {
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 14px;
  padding: 14px 16px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
  height: 200px;
  overflow: auto;
}
.info-card__title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
  font-size: 14px;
  color: var(--el-text-color-primary);
  margin-bottom: 10px;
}

/* 设备信息（去重边框，弱化线条） */
.kv :deep(.el-descriptions__table.is-bordered) {
  border: none;
}
.kv :deep(.el-descriptions__cell) {
  border: none;
  padding: 6px 8px;
}
.kv :deep(.el-descriptions__label) {
  color: var(--el-text-color-secondary);
  width: 86px;
}

/* 备件表更轻量 */
.spare-table :deep(.el-table__header-wrapper th) {
  background: var(--el-fill-color-light);
}
.spare-table :deep(.el-table__inner-wrapper)::before {
  display: none;
}

/* 自适应 */
@media (max-width: 1280px) {
  .info-grid.cols3 {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 860px) {
  .info-grid.cols3,
  .info-grid.cols2 {
    grid-template-columns: 1fr;
  }
}

/* .plan-table {
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.05);
} */

/* 外层容器不滚动，下面的 body 占满剩余空间 */
.wo-wrap {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}

/* body 里用列布局，让“表格卡片”吃满高度 */
.wo-body {
  flex: 1;
  min-height: 0; /* 防止子项被撑爆 */
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 1px 14px;
  box-sizing: border-box;
}

/* 表格卡片也用列布局，内部滚动交给表格本身 */
.table-card {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid #edf0f4;
  border-radius: 10px;
  box-shadow: 0 6px 20px rgba(28, 39, 60, 0.06);
  background: #fff;
  overflow: hidden;
}

/* 让 el-table 的 100% 有参照物 */
.table-holder {
  flex: 1;
  min-height: 0; /* 允许内部滚动 */
}

/* 分页粘在可视区底部（相对于滚动容器） */
.wo-pager {
  position: sticky;
  bottom: 0;
  z-index: 5;
  background: #fff; /* 避免与表格重叠时透出 */
  border-top: 1px solid #eef2f6;
  padding: 6px 8px;
  display: flex;
  justify-content: flex-end;
}
</style>
